package com.overlord.im.connector.start;

import com.overlord.im.connector.netty.channel.ImServerChannelInitializer;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.net.InetSocketAddress;

/**
 * @ClassName ImServer
 * @Author wuwei
 * @Description NONE
 * @Date 2020/5/9 11:12
 **/
@Slf4j
@Component
public class ImServer {

    /**
     * boss 线程组用于处理连接工作
     */
    private EventLoopGroup boss = new NioEventLoopGroup();
    /**
     * work 线程组用于数据处理
     */
    private EventLoopGroup work = new NioEventLoopGroup();

    @Resource
    private ImServerChannelInitializer imServerChannelInitializer;

    @Resource
    private ConnectorRegister connectorRegister;
    @Value("${im.server.port}")
    private Integer port;
    @Value("${im.server.host}")
    private String ip;
    @Value("${im.server.name}")
    private String serverName;

    @PostConstruct
    public void start() throws InterruptedException {
        log.info("starting IM handler ...");
        ServerBootstrap bootstrap = new ServerBootstrap();
        bootstrap.group(boss, work)
                // 指定Channel
                .channel(NioServerSocketChannel.class)
                //使用指定的端口设置套接字地址
                .localAddress(new InetSocketAddress(port))

                //服务端可连接队列数,对应TCP/IP协议listen函数中backlog参数
                .option(ChannelOption.SO_BACKLOG, 1024)

                //设置TCP长连接,一般如果两个小时内没有数据的通信时,TCP会自动发送一个活动探测数据报文
                .childOption(ChannelOption.SO_KEEPALIVE, true)

                //将小的数据包包装成更大的帧进行传送，提高网络的负载
                .childOption(ChannelOption.TCP_NODELAY, true)

                .childHandler(imServerChannelInitializer);
        ChannelFuture future = bootstrap.bind().sync();
        if (future.isSuccess()) {

            connectorRegister.register(ip, String.valueOf(port));
            log.info("IM handler start success ...");
        }
    }

}
